package service

import (
	infraSvc "cat_mouse/infra/service"
	"cat_mouse/infra/utils"
	"cat_mouse/infra/utils/log"
	"fmt"
	"sync"
	"time"
)

// 房间回复消息结构体
type replyMsg struct {
	Broadcast bool
	MsgType   int // 1-加入房间|2-退出房间|3-房间结束|4-开始游戏|5-坐标信息|6-回复消息
	Msg       string
	UserId    string
	UserName  string
}

type receiveMsg struct {
	MsgType   int
	UserId    string
	UserName  string
	Latitude  float64
	Longitude float64
}

// 坐标位置结构体
type location struct {
	Latitude  float64
	Longitude float64
}

type syncFun func()

type Engine struct {
	lock           sync.Mutex                    // 锁
	cats           map[string]struct{}           // 定义猫的集合
	rats           map[string]struct{}           // 定义老鼠的集合
	memberMax      int                           // 房间最大人数
	password       string                        // 房间密码
	members        sync.Map                      // 房间用户ID集合
	ownerId        string                        // 房主ID
	ownerName      string                        // 房主名称
	timer          *time.Timer                   // 房间游戏计时器
	userWs         map[string]*infraSvc.WsClient // 房间用户websocket连接
	startSignal    chan struct{}                 // 定义房间开始标志
	stopSignal     chan struct{}                 // 定义房间结束标志
	receiveMsgCh   chan interface{}              // 房间接受到的用户信息
	replyMsgCh     chan replyMsg                 // 房间回复消息管道
	logCh          chan string                   // 定义需要记录的日志文件
	latestLocation map[string]location           // 定义用户最新的坐标经纬度值
	syncListeners  []syncFun                     // 定义需要异步执行的监听任务
}

// 准备阶段分2个步骤，第一阶段是留10分钟的时间等待用户的加入，待人数超过5个以后进入第二阶段，如果在10分钟内还没有用户加入，游戏结束。
// 第二阶段主要是让用户有自由逃跑的时间，期限5分钟，5分钟后会随机分配猫和老鼠的角色
func (e *Engine) prepare() {
	prepareStatus := false
	for {
		select {
		case <-e.timer.C:
			if prepareStatus {
				e.randomRole()
				e.replyMsgCh <- replyMsg{
					MsgType: 4,
					Msg:     "猫鼠已分配，开始游戏",
				}
				e.timer.Reset(1 * time.Hour)
				e.startSignal <- struct{}{}
				return
			}
			if len(e.userWs) < 5 {
				log.Logger.Error("人数少于5，游戏结束")
				e.stopSignal <- struct{}{}
				return
			}
			prepareStatus = true
		}
		e.timer.Reset(5 * time.Minute)
	}
}

// 游戏开始时候随机生成一只猫,其余全部是老鼠
func (e *Engine) randomRole() {
	length := len(e.userWs)
	seed := utils.RandomInt(0, length-1)
	idx := 0
	for k, _ := range e.userWs {
		if idx == seed {
			e.cats[k] = struct{}{}
			e.replyMsgCh <- replyMsg{
				MsgType: 6,
				Msg:     "Cat",
				UserId:  k,
			}
		}
		e.rats[k] = struct{}{}
		e.replyMsgCh <- replyMsg{
			MsgType: 6,
			Msg:     "Rat",
			UserId:  k,
		}
		idx++
	}
}

func (e *Engine) Join() {

}

func (e *Engine) GetReceiveCh() chan interface{} {
	return e.receiveMsgCh
}

func (e *Engine) stop() {
	close(e.startSignal)
	close(e.stopSignal)
	close(e.receiveMsgCh)
	close(e.replyMsgCh)
	close(e.logCh)
}

func (e *Engine) dispatch() {
	go e.prepare()
	defer e.timer.Stop()
	defer e.stop()

	select {
	case <-e.stopSignal:
		e.stop()
		return
	case <-e.startSignal:
		for _, v := range e.syncListeners {
			go v()
		}
		for {
			select {
			case msg, _ := <-e.receiveMsgCh:
				switch msg.(receiveMsg).MsgType {
				case 1, 2, 3, 4:
					e.replyMsgCh <- replyMsg{
						Broadcast: true,
						MsgType:   4,
						Msg:       "...",
					}
				case 5:
					fmt.Println(4)
				}
			case <-e.timer.C:
				return
			case <-e.stopSignal:
				return
			}
		}
	}
}
